﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using JsonException = Newtonsoft.Json.JsonException;
using JsonSerializer = Newtonsoft.Json.JsonSerializer;

namespace Infrastructure.Extensions
{
    /// <summary>
    /// JsonElement 扩展方法工具类
    /// 提供从 JSON 数组快速反序列化对象和元组的便捷方法
    /// </summary>
    public static class JsonExtension
    {
        /// <summary>
        /// 从 JSON 数组中获取指定索引的元素并反序列化为指定类型
        /// </summary>
        /// <typeparam name="T">目标类型</typeparam>
        /// <param name="json">JsonElement 对象（必须为 JSON 数组）</param>
        /// <param name="index">数组索引</param>
        /// <returns>
        /// 反序列化后的对象，如果数组为空返回默认值
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">索引超出数组范围时抛出</exception>
        /// <exception cref="JsonException">JSON 结构不符合预期时抛出</exception>
        public static T Get<T>(this JsonElement json, int index)
        {
            // 验证 JSON 元素是否为数组
            if (json.ValueKind != JsonValueKind.Array)
                throw new JsonException("JSON element is not an array");

            // 获取数组长度
            var arrayLength = json.GetArrayLength();

            // 处理空数组
            if (arrayLength == 0) return default;

            // 索引范围校验
            if (index < 0 || index >= arrayLength)
                throw new ArgumentOutOfRangeException(
                    nameof(index),
                    $"Index [{index}] is out of range. Array length: {arrayLength}"
                );

            // 使用 Newtonsoft.Json 反序列化
            var token = JToken.Parse(json[index].GetRawText());
            return token.ToObject<T>();
        }

        /// <summary>
        /// 从 JSON 数组中获取第一个元素并反序列化为指定类型
        /// </summary>
        public static T Get<T>(this JsonElement json) => json.Get<T>(0);

        /// <summary>
        /// 从 JSON 数组中提取前两个元素并打包为元组
        /// </summary>
        /// <returns>(T1, T2) 元组</returns>
        public static (T1, T2) Get<T1, T2>(this JsonElement json)
            => (json.Get<T1>(0), json.Get<T2>(1));

        // 其他元组方法（注释结构类似，省略重复部分）
        // ---------------------------------------------------------
        // 建议：实际开发中可改为可变参数泛型方法减少重复代码
        // public static T[] GetArray<T>(this JsonElement json, params int[] indexes)
        // ---------------------------------------------------------

        /// <summary>
        /// 从 JSON 数组中提取前六个元素并打包为元组（示例）
        /// </summary>
        public static (T1, T2, T3, T4, T5, T6) Get<T1, T2, T3, T4, T5, T6>(this JsonElement json)
            => (json.Get<T1>(0), json.Get<T2>(1), json.Get<T3>(2),
                json.Get<T4>(3), json.Get<T5>(4), json.Get<T6>(5));
    }
}
